//
//  HookDispatcher.m
//  Staff
//
//  Created by caiyao on 1/6/15.
//
//

#import "HookDispatcher.h"
#import "HookCommand.h"
#import "HookAPI.h"
#import "Constants.h"

@implementation HookDispatcher

- (void)dealloc {
    [_commandQueue release];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:COMMAND_EXCUTE_DONE_NOTIFICATION object:nil];
    [super dealloc];
}

- (id)init {
    if (self = [super init]) {
        _commandQueue = [[NSMutableArray alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskFinished:) name:COMMAND_EXCUTE_DONE_NOTIFICATION object:nil];
    }
    return self;
}

- (void)dispatchRequest:(NSURLRequest *)request webView:(UIWebView *)webView hookWebViewController:(HookWebViewController *)controller { 
    HookCommand *hookCommand = [HookCommand parserHookCommandFromRequest:request];
    HookAPI *hookApi = [[NSClassFromString(hookCommand.functionName) alloc] initWithHookCommand:hookCommand webView:webView hookViewController:controller];
    if (hookApi) {
        [self inQueue:hookApi];
    } else {
        [self excuteNonHookFoundCallbackWithCommand:hookCommand webView:webView];
    }
}

- (void)inQueue:(HookAPI *)hookAPI {
    [_commandQueue addObject:hookAPI];
    [self scanQueue];
}

- (void)scanQueue
{
    for (int i=0; i<_commandQueue.count; i++) {
        HookAPI *command = (HookAPI *)[_commandQueue objectAtIndex:i];
        if (command.excuteStatus == HookAPI_EXCUTE_STATUS_READY)
        {
            [command excute];
        }
    }
}

- (void)taskFinished:(NSNotification *)notify
{
    @synchronized(self)
    {
        [_commandQueue removeObject:notify.object];
    }
}

- (void)excuteNonHookFoundCallbackWithCommand:(HookCommand *)hookCommand webView:(UIWebView *)webView{
    NSString *jsFailCallBack = [NSString stringWithFormat:region_webview_statusCall,
                                region_webview_hookAPIFailCall,
                                CNS_STATUS_HOOKAPI_ERR];
    
    DebugLog(@"jsFailCallBack is %@",jsFailCallBack);
    
    [webView stringByEvaluatingJavaScriptFromString:jsFailCallBack];
}

@end
